﻿/*****************************************************************//**
 * @file    FITKAcousticsVTKSharedDataManager.h
 * @brief   The VTK sharable data manager.
 *  
 * @author  ChengHaotian (yeguangbaozi@foxmail.com)
 * @date    2024-11-08
 *********************************************************************/

#ifndef __FITKACOUSTICSVTKSHAREDDATAMANAGER_H__
#define __FITKACOUSTICSVTKSHAREDDATAMANAGER_H__

#include <QObject>
#include <QHash>

// The data array name for picking and rendering color.
//@{
#define DATA_ID_ARRAY_NAME          "__data_id__"
#define DATA_SUB_ID_ARRAY_NAME      "__data_sub_id__"
#define DATA_ELEM_ID_ARRAY_NAME     "__data_element_id__"
#define DATA_COLOR_ARRAY_NAME       "__data_color__"
#define DATA_POST_NULL_ARRAY_NAME   "__post_null_color__"
//@}

// The keys of the picture data dict.
//@{
#define PIC_TYPE_SIF                  1
#define PIC_TYPE_SIF_HL               2
#define PIC_TYPE_SIF_DIS              3
#define PIC_TYPE_SIF_HL_DIS           4
#define PIC_TYPE_POWER                5
#define PIC_TYPE_POWER_HL             6
#define PIC_TYPE_POWER_DIS            7
#define PIC_TYPE_POWER_HL_DIS         8
#define PIC_TYPE_CONSTRAINT           9
#define PIC_TYPE_CONSTRAINT_HL        10
#define PIC_TYPE_CONSTRAINT_DIS       11
#define PIC_TYPE_CONSTRAINT_HL_DIS    12
#define PIC_TYPE_IMPORT               13
#define PIC_TYPE_IMPORT_HL            14
#define PIC_TYPE_IMPORT_DIS           15
#define PIC_TYPE_IMPORT_HL_DIS        16
#define PIC_TYPE_MONOPOLE             13
#define PIC_TYPE_MONOPOLE_HL          14
#define PIC_TYPE_MONOPOLE_DIS         15
#define PIC_TYPE_MONOPOLE_HL_DIS      16
//@}

// Forward declaration
class vtkPoints;
class vtkMultiBlockDataSet;
class vtkDataSet;
class vtkImageData;
class vtkUnsignedCharArray;

namespace Acoustics
{
    class FITKAcousticsDiscModel;
    class FITKAcousticsSEAModel;
    class FITKAcousticsFEModel;
    class FITKAcousticsDiscNodeList;
    class FITKAcousticsSEASubSysManager;
    class FITKAbstractSEASubSys;
    class FITKJunctionManager;
}

namespace Exchange
{
    /**
     * @brief   The VTK sharable data manager.
     * @author  ChengHaotian (yeguangbaozi@foxmail.com)
     * @date    2024-11-08
     */
    class FITKAcousticsVTKSharedDataManager : public QObject
    {
        Q_OBJECT
    public:
        /**
         * @brief   Get the instance of this class.[static]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-08
         */
        static FITKAcousticsVTKSharedDataManager* GetInstance();

        /**
         * @brief   Delete the instance.[static]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-08
         */
        static void Destory();

        // VTK Data.
        //@{
        // SEA nodes.
        //@{
        /**
         * @brief   Get the SEA nodes points data.
         * @param   reCreate: Re-generate the points[default]
         * @return  The VTK points data
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-08
         */
        vtkPoints* getSEANodesPoints(bool reCreate = false);

        /**
         * @brief   Get the boundary of all SEA nodes.
         * @param   bds6: The boundary of all SEA nodes
         * @return  Is the bounds valid
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-13
         */
        bool getSEANodesBounds(double* bds6);

        /**
         * @brief   Get the center of all SEA nodes.
         * @param   pos3: The center of all SEA nodes
         * @return  Is the position valid
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-13
         */
        bool getSEANodesCenter(double* pos3);
        //@}

        // SEA subs-systems.
        //@{
        /**
         * @brief   Get the multi block dataset of the given type of SEA sub-systems.
         * @param   seaSubSysEnum: The SEA sub-system type
         * @return  The dataset
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-15
         */
        vtkMultiBlockDataSet* getSEASubSystemsMultiDataSet(int seaSubSysEnum);

        /**
         * @brief   Get the boundary multi block dataset of the given type of SEA sub-systems.
         * @param   seaSubSysEnum: The SEA sub-system type
         * @return  The dataset
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-19
         */
        vtkMultiBlockDataSet* getSEASubSystemsBoundaryMultiDataSet(int seaSubSysEnum);
        /**
         * @brief    获取FE面数据块
         * @return   vtkMultiBlockDataSet*         FE面数据块
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-12-31
         */
        vtkMultiBlockDataSet* getFEFaceMultiDataSet();
        /**
         * @brief    根据FE子系统的类型获取数据块
         * @param[i] seaSubSysEnum                    FE子系统类型
         * @return   vtkMultiBlockDataSet*            数据块
         * @author   BaGuijun (baguijun@163.com)
         * @date     2025-01-02
         */
        vtkMultiBlockDataSet* getFESubSysMultiDataSet(int seaSubSysEnum);

        /**
         * @brief   Get the dataset of the given data id of SEA sub-system.
         * @param   dataId: The SEA sub-system data id
         * @param   blockIndex: The index of the dataset in the multi block dataset[quote]
         * @return  The dataset
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-18
         */
        vtkDataSet* getSEASubSystemDataSet(int dataId, int & blockIndex);
        vtkDataSet* getSEASubSystemBoundaryDataSet(int dataId, int & blockIndex);
        /**
         * @brief    获取数据id对应的数据块与数据块索引
         * @param[i] dataId                     数据id
         * @param[o] blockIndex                 数据块索引
         * @return   vtkDataSet*                数据块
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-12-30
         */
        vtkDataSet* getFEFacesDataSet(int dataId, int & blockIndex);
        /**
         * @brief    获取数据id对应的数据块与数据块索引
         * @param[i] dataId                     数据id
         * @param[o] blockIndex                 数据块索引
         * @return   vtkDataSet*                数据块
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-12-30
         */
        vtkDataSet* getFESubSystemDataSet(int dataId, int & blockIndex);
        /**
         * @brief   (Re-)Generate the dataset of the given id.
         * @param   dataId: The SEA sub-system data object id
         * @return  Is the data id valid
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-15
         */
        bool updateSEASubSystemDataSet(int dataId);
        /**
         * @brief   (Re-)Generate the dataset of the given id.
         * @param   dataId: The SEA junction data object id
         * @return  Is the data id valid
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-19
         */
        bool updateSEAJunctionDataSet(int dataId);
        /**
         * @brief    更新FE子系统
         * @param[i] dataId            FE子系统id
         * @return   bool              是否成功
         * @author   BaGuijun (baguijun@163.com)
         * @date     2025-01-02
         */
        bool updateFESubSystemDataSet(int dataId);
        /**
         * @brief    更新FE面
         * @param[i] dataId             数据id
         * @return   bool               是否成功
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-12-30
         */
        bool updateFEFaceDataSet(int dataId);
        /**
         * @brief   Update the SEA sub-system data color array.
         * @param   dataId: The SEA sub-system data id
         * @return  Is the data id valid
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-22
         */
        bool updateSEASubSystemDataSetColor(int dataId);
        /**
         * @brief   Update the SEA junction data color array.
         * @param   dataId: The SEA junction data id
         * @return  Is the data id valid
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-22
         */
        bool updateSEAJunctionDataSetColor(int dataId);
        /**
         * @brief    更新FE子系统对象颜色
         * @param[i] dataId                  id
         * @return   bool                    是否成功
         * @author   BaGuijun (baguijun@163.com)
         * @date     2025-01-02
         */
        bool updateFESubSystemDataSetColor(int dataId);
        /**
         * @brief    更新FE面的颜色
         * @param[i] dataId             数据id
         * @return   bool               是否成功
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-12-31
         */
        bool updateFEFaceDataSetColor(int dataId);
        //@}

        // SEA junctions.
        //@{
        /**
         * @brief   Get the multi block dataset of the given type of SEA junctions.
         * @param   seaJuncEnum: The SEA junction type
         * @return  The dataset
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-19
         */
        vtkMultiBlockDataSet* getSEAJunctionsMultiDataSet(int seaJuncEnum);

        /**
         * @brief   Get the dataset of the given data id of SEA junction.
         * @param   dataId: The SEA junction data id
         * @param   blockIndex: The index of the dataset in the multi block dataset[quote]
         * @return  The dataset
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-19
         */
        vtkDataSet* getSEAJunctionDataSet(int dataId, int & blockIndex);



    
        //@}

        /**
         * @brief   Get the dataset of the given data id.
         * @param   dataId: The data id
         * @return  The dataset
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-18
         */
        vtkDataSet* getDataSetByDataId(int dataId);
        //@}

        // Global param.
        //@{
        /**
         * @brief   Get the world size of the nodes by global size ratio.
         * @return  The size of the (SEA) nodes
         * @param   scaleFactor: The scale factor of the value
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-13
         */
        double getNodeWorldSizeByRatio(double scaleFactor = 1.);

        /**
         * @brief   Get the world size of the nodes by global size ratio and the density of the nodes.
         * @return  The size of the (SEA) nodes
         * @param   scaleFactor: The scale factor of the value
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-13
         */
        double getNodeWorldSizeByRatioWithDensity(double scaleFactor = 1.);

        /**
         * @brief   Get the world size of the tube radius by global size ratio.
         * @return  The radius of the tube 
         * @param   scaleFactor: The scale factor of the value
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-15
         */
        double getTubeWorldSizeByRatio(double scaleFactor = 1.);
        //@}

        // Global data.
        //@{
        /**
         * @brief   Get the SEA semi-infinite-fluid picture source data.
         * @param   enable: Is the data enabled[default]
         * @param   highlight: The highlight picture[default]
         * @return  The image data of the picture
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-21
         */
        vtkImageData* getSEASemiInfFluidPicData(bool enable = true, bool highlight = false);

        /**
         * @brief   Get the user defined power picture source data.
         * @param   enable: Is the data enabled[default]
         * @param   highlight: The highlight picture[default]
         * @return  The image data of the picture
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-25
         */
        vtkImageData* getLoadPowerPicData(bool enable = true, bool highlight = false);

        /**
         * @brief   Get the constraint picture source data.
         * @param   enable: Is the data enabled[default]
         * @param   highlight: The highlight picture[default]
         * @return  The image data of the picture
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-25
         */
        vtkImageData* getLoadConstraintPicData(bool enable = true, bool highlight = false);
        /**
         * @brief    获取导入载荷照片数据对象
         * @param[i] enable                 是否启用
         * @param[i] highlight              是否高亮
         * @return   vtkImageData*          图片数据对象
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-12-11
         */
        vtkImageData* getLoadImportPicData(bool enable = true, bool highlight = false);
        /**
         * @brief    获取单极子载荷照片数据对象
         * @param[i] enable                 是否启用
         * @param[i] highlight              是否高亮
         * @return   vtkImageData*          图片数据对象
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-12-11
         */
        vtkImageData* getLoadMonopolePicData(bool enable = true, bool highlight = false);
        //@}
    private:
        /**
         * @brief   Constructure.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-08
         */
        FITKAcousticsVTKSharedDataManager();

        /**
         * @brief   Desturcture.[virtual]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-08
         */
        virtual ~FITKAcousticsVTKSharedDataManager();

        /**
         * @brief   Internal function - Generate the vtkPoints for the sub-system with the SEA nodes.
         * @param   seaSubSys: The SEA sub-system
         * @param   points: The SEA sub-system points
         * @param   nodeIdPointIndexHash: The used SEA node id and vtk point index hash[quote]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-15
         */
        void generateSEASubSysNodes(Acoustics::FITKAbstractSEASubSys* seaSubSys, vtkPoints* points, QHash<int, int> & nodeIdPointIndexHash);

        /**
         * @brief   Delete the VTK none-smartpointer objects.
         * @param   objs: The vtkObject hash.[quote]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-19
         */
        void deleteVtkObjs(QHash<int, vtkMultiBlockDataSet*> & objs);

        /**
         * @brief   Add the color array with the color to the dataset.
         * @param   dataSet: The dataset
         * @param   color: The color
         * @param   arrayName: The color array name
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-20
         */
        void setDataSetColor(vtkDataSet* dataSet, QColor color, QString arrayName);

        /**
         * @brief   Add the color array with the front face color and the back face color to the dataset.
         * @param   dataSet: The dataset
         * @param   colorFront: The front face color
         * @param   colorBack: The back face color
         * @param   arrayName: The color array name
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-21
         */
        void setDataSetColor(vtkDataSet* dataSet, QColor colorFront, QColor colorBack, QString arrayName);
        /**
         * @brief    设置数据颜色
         * @param[i] dataSet                              数据对象
         * @param[i] colorArray                           颜色数组
         * @author   BaGuijun (baguijun@163.com)
         * @date     2025-01-20
         */
        void setDataSetColor(vtkDataSet* dataSet, vtkUnsignedCharArray* colorArray);

        /**
         * @brief   Internal function - Remove the cache file, copy the qrc file to the dest file path and read the picture.
         * @param   resFilePath: The qrc file path
         * @param   destFilePath: The dest file path
         * @param   imageData: The image data of the picture
         * @return  Is the picture valid
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-25
         */
        bool removeCacheFileAndReadPicture(QString resFilePath, QString destFilePath, vtkImageData* imageData);

        /**
         * @brief   Internal function - Get the file suffix name with the enable flag and highlight flag.
         * @param   enable: Is the data enabled
         * @param   highlight: Is the data highlighted
         * @return  The file suffix
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-26
         */
        QString getSuffixByDataFlag(bool enable, bool highlight);

    private:
        /**
         * @brief   The instance of the class.[static]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-08
         */
        static FITKAcousticsVTKSharedDataManager* s_instance;

        /**
         * @brief   The acoustics data set.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-15
         */
        Acoustics::FITKAcousticsDiscModel* m_discModel{ nullptr };

        /**
         * @brief   The SEA model data.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-15
         */
        Acoustics::FITKAcousticsSEAModel* m_SEAModel{ nullptr };

        /**
         * @brief   The FE model data.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-15
         */
        Acoustics::FITKAcousticsFEModel* m_FEModel{ nullptr };

        /**
         * @brief   The SEA node list.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-15
         */
        Acoustics::FITKAcousticsDiscNodeList* m_SEANodes{ nullptr };

        /**
         * @brief   The SEA sub-system manager.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-15
         */
        Acoustics::FITKAcousticsSEASubSysManager* m_SEASubSysMgr{ nullptr };

        /**
         * @brief   The SEA junction manager.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-19
         */
        Acoustics::FITKJunctionManager* m_SEAJuncMgr{ nullptr };

        /**
         * @brief   The VTK points data of the SEA-nodes.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-08
         */
        vtkPoints* m_SEANodesPoints{ nullptr };

        /**
         * @brief   The dict for SEA sub-system dataset.
         *          The key is the SEA sub-system type enum value.
         *          The value is the dataset for all this kind of sub-systems.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-15
         */
        QHash<int, vtkMultiBlockDataSet*> m_SEASubSystemsDataSetHash;

        /**
         * @brief   The dict for SEA sub-system boundary dataset.
         *          The key is the SEA sub-system type enum value.
         *          The value is the boundary line dataset for all this kind of sub-systems.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-19
         */
        QHash<int, vtkMultiBlockDataSet*> m_SEASubSystemsBoundDataSetHash;

        /**
         * @brief   The dict for SEA junction dataset.
         *          The key is the SEA junction type enum value.
         *          The value is the dataset for all this kind of junction.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-19
         */
        QHash<int, vtkMultiBlockDataSet*> m_SEAJunctionsDataSetHash;

        /**
         * @brief   The dict for SEA sub-system dataset.
         *          The key is the SEA sub-system data object id.
         *          The value is the dataset for all this kind of sub-systems.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-26
         */
        QHash<int, vtkMultiBlockDataSet*> m_SEASubSysDataObjDataSetHash;

        /**
         * @brief   The dict for SEA sub-system dataset for boundary.
         *          The key is the SEA sub-system data object id.
         *          The value is the boundary line dataset for all this kind of sub-systems.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-26
         */
        QHash<int, vtkMultiBlockDataSet*> m_SEASubSysDataObjBdsDataSetHash;

        /**
         * @brief   The dict for SEA junction dataset.
         *          The key is the SEA junction data object id.
         *          The value is the dataset for all this kind of junction.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-26
         */
        QHash<int, vtkMultiBlockDataSet*> m_SEAJuncDataObjDataSetHash;
        /**
         * @brief  FE面数据块
         * @author BaGuijun (baguijun@163.com)
         * @date   2024-12-30
         */
        vtkMultiBlockDataSet* m_FEFaceObjDataSet = nullptr;
        /**
         * @brief  FE子系统数据块
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-01-02
         */
        QHash<int, vtkMultiBlockDataSet*> m_FESubSysDataObjSetHash;
        /**
         * @brief   The dict for SEA sub-system dataset.
         *          The key is the SEA sub-system data object.
         *          The value is the dataset of the sub-system.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-15
         */
        QHash<void*, vtkDataSet*> m_SEASubSysDataSetHash;

        /**
         * @brief   The dict for SEA sub-system boundary dataset.
         *          The key is the SEA sub-system data object.
         *          The value is the boundary dataset of the sub-system.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-19
         */
        QHash<void*, vtkDataSet*> m_SEASubSysBoundDataSetHash;

        /**
         * @brief   The dict for SEA dataset.
         *          The key is the SEA junction data object.
         *          The value is the dataset of the junction.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-19
         */
        QHash<void*, vtkDataSet*> m_SEAJuncDataSetHash;

        /**
         * @brief   The dict for all pictures of the graph object.
         *          The key is the defined integer value.
         *          The value is the vtkImageData of the picture.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-11-21
         */
        QHash<int, vtkImageData*> m_picDataDict;
        /**
         * @brief  FE面渲染数据管理hash
         * @author BaGuijun (baguijun@163.com)
         * @date   2024-12-30
         */
        QHash<void*, vtkDataSet*> m_FEFaceDataSetHash;
        /**
         * @brief  FE子系统渲染数据管理hash
         * @author BaGuijun (baguijun@163.com)
         * @date   2025-01-02
         */
        QHash<void*, vtkDataSet*> m_FESubSysDataSetHash;

    };
}   // namespace Exchange

#endif // __FITKACOUSTICSVTKSHAREDDATAMANAGER_H__
